package com.sky.service.impl;

import com.sky.context.BaseContext;
import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.workspaceService;
import com.sky.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ReposrtServiceImpl implements ReportService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private workspaceService workspaceService;


    /**
     * 营业额统计
     * @param begin
     * @param end
     * @return
     */
    public TurnoverReportVO turnoverReport(LocalDate begin, LocalDate end) {
        List<LocalDate> datesList = new ArrayList<>();
        datesList.add(begin);

        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            datesList.add(begin);
        }

        String dateList = StringUtils.join(datesList, ",");

        List<Double> turnoverList = new ArrayList<>();

        for (LocalDate date : datesList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            Map map = new HashMap();
            map.put("begin",beginTime);
            map.put("end",endTime);
            map.put("status", Orders.COMPLETED);

            Double turnover = orderMapper.sumByMap(map);
            if (turnover == null ){
                turnoverList.add(0.0);
            }else {
                turnoverList.add(turnover);
            }
        }

        String turnovers = StringUtils.join(turnoverList, ",");

        TurnoverReportVO turnoverReportVO = TurnoverReportVO.builder()
                .dateList(dateList)
                .turnoverList(turnovers)
                .build();

        return turnoverReportVO;
    }

    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    public UserReportVO userReport(LocalDate begin, LocalDate end) {
        UserReportVO userReportVO = new UserReportVO();

        //统计日期
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);

        while (!begin.equals(end)){
            begin = begin.plusDays(1);

            dateList.add(begin);
        }

        String json = StringUtils.join(dateList, ",");
        userReportVO.setDateList(json);

        //统计用户总量
        List<Integer> totalUserLists = new ArrayList<>();
        //统计单日新增用户量
        List<Integer> newUserLists = new ArrayList<>();

        for (LocalDate localDate : dateList) {
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);

            Map map = new HashMap();
            map.put("end",endTime);
            Integer totalUser = userMapper.getUserByTime(map);
            totalUserLists.add(totalUser);

            map.put("begin",beginTime);
            Integer newUser = userMapper.getUserByTime(map);
            newUserLists.add(newUser);
            }

        String totalUserList = StringUtils.join(totalUserLists, ",");
        userReportVO.setTotalUserList(totalUserList);

        String newUserList = StringUtils.join(newUserLists, ",");
        userReportVO.setNewUserList(newUserList);

        return userReportVO;
    }

    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    public OrderReportVO orderReport(LocalDate begin, LocalDate end) {

        //统计日期
        List<LocalDate> dateLists = new ArrayList<>();
        dateLists.add(begin);

        while (!begin.equals(end)){
            begin = begin.plusDays(1);

            dateLists.add(begin);
        }
        String dateList = StringUtils.join(dateLists, ",");

        List<Integer> orderCountLists = new ArrayList<>();
        List<Integer> validOrderCountLists = new ArrayList<>();
        for (LocalDate date : dateLists) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            Map map = new HashMap();
            map.put("begin",beginTime);
            map.put("end",endTime);

            //每日订单数
            Integer sum = orderMapper.getCount(map);
            if (sum == null){
                orderCountLists.add(0);
            }else {
                orderCountLists.add(sum);
            }

            //每日有效订单数
            map.put("status",Orders.COMPLETED);

            Integer count = orderMapper.getCount(map);
            if (sum == null){
                validOrderCountLists.add(0);
            }else {
                validOrderCountLists.add(count);
            }

        }

        String orderCountList = StringUtils.join(orderCountLists, ",");
        String validOrderCountList = StringUtils.join(validOrderCountLists, ",");

        //订单总数
        Map mapDay = new HashMap();
        Integer totalOrder = orderMapper.getCount(mapDay);

        //有效订单数
         mapDay.put("status", Orders.COMPLETED);
        Integer validOrder = orderMapper.getCount(mapDay);

        //订单完成率
        Double orderCompletionRate = (double) (validOrder / totalOrder);

        OrderReportVO orderReportVO = OrderReportVO.builder()
                .dateList(dateList)
                .orderCountList(orderCountList)
                .validOrderCountList(validOrderCountList)
                .totalOrderCount(totalOrder)
                .validOrderCount(validOrder)
                .orderCompletionRate(orderCompletionRate)
                .build();

        return orderReportVO;
    }

    /**
     * 查询销量排名top10
     * @param begin
     * @param end
     * @return
     */
    public SalesTop10ReportVO orderTopReport(LocalDate begin, LocalDate end) {

        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        List<GoodsSalesDTO> orderTopReport = orderMapper.getOrderTopReport(beginTime,endTime);

        List<String> names = orderTopReport.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        String namesList = StringUtils.join(names, ",");

        List<Integer> numbers = orderTopReport.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        String numberList = StringUtils.join(numbers, ",");

        SalesTop10ReportVO salesTop10ReportVO = SalesTop10ReportVO.builder()
                .nameList(namesList)
                .numberList(numberList)
                .build();

        return salesTop10ReportVO;
    }

    /**
     * 导出Excel报表
     * @param response
     */
    public void exportBusinessDat(HttpServletResponse response) {
        LocalDate beginDate = LocalDate.now().minusDays(30);
        LocalDate endDate = LocalDate.now().minusDays(1);

        LocalDateTime beginTime = LocalDateTime.of(beginDate, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(endDate, LocalTime.MAX);

        //查询概览数据
        BusinessDataVO businessDataVO = workspaceService.businessData(beginTime,endTime);

        //通过POI将数据写入到Excel文件中
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");

        try {
            //基于模板文件创建一个新的Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(in);

            //获取sheet1表
            XSSFSheet sheet = excel.getSheet("sheet1");

            //获取第二行  填充数据
            XSSFRow row2 = sheet.getRow(1);
            XSSFCell cell = row2.getCell(1);
            cell.setCellValue("时间："+ beginDate + "至" + endDate);

            //填充第四行数据
            XSSFRow row4 = sheet.getRow(3);
            row4.getCell(2).setCellValue(businessDataVO.getTurnover());
            row4.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row4.getCell(6).setCellValue(businessDataVO.getNewUsers());

            //填充第五行数据
            XSSFRow row5 = sheet.getRow(4);
            row5.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row5.getCell(4).setCellValue(businessDataVO.getUnitPrice());

            for (int i = 0; i < 30; i++) {
                LocalDate date = beginDate.plusDays(i);

                BusinessDataVO businessData = workspaceService.businessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));

                //获得某一行
                XSSFRow row = sheet.getRow(7 + i);

                row.getCell(1).setCellValue(String.valueOf(date));
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());

            }

            //通过输出流将Excel文件下载到客户端浏览器
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

            //关闭资源
            outputStream.close();
            excel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}
